﻿using System;
using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MugenInjection;
using MugenInjection.Attributes;
using Should;

namespace MugenInjectionTest.Attributes
{
    [TestClass]
    public class OptionalParameterAttributeTest : TestBase
    {
        [TestMethod]
        public void OptionalAttributeTest()
        {
            using (var injector = GetInjector())
            {
                injector.Bind<OptionalAttributeClass>().ToSelf();
                var optionalAttributeClass = injector.Get<OptionalAttributeClass>();
                optionalAttributeClass.Property.ShouldEqual("Property");
                optionalAttributeClass.MethodParameter.ShouldEqual("methodParameter");
                optionalAttributeClass.ConstructorParameter.ShouldEqual("parameter");
                optionalAttributeClass.Default.ShouldBeNull();
                optionalAttributeClass.DefaultValue.ShouldEqual(default(int));

                const int i = 10;
                const string st = "commonString";
                IDisposable disposable = GetInjector();
                injector.Bind<string>().ToConstant(st);
                injector.Bind<int>().ToConstant(i);
                injector.Bind<IDisposable>().ToConstant(disposable);

                optionalAttributeClass = injector.Get<OptionalAttributeClass>();
                optionalAttributeClass.Property.ShouldEqual(st);
                optionalAttributeClass.MethodParameter.ShouldEqual(st);
                optionalAttributeClass.ConstructorParameter.ShouldEqual(st);
                optionalAttributeClass.Default.ShouldEqual(disposable);
                optionalAttributeClass.DefaultValue.ShouldEqual(i);
            }
        }

        /*[TestMethod]
        public void OptionalAttributeWithComplexTypesTest()
        {
            using (var injector = GetInjector())
            {
                const string constName = "constName";
                injector.Bind<OptionalAttributeClassWithFactory>().ToSelf();

                var classWithFactory = injector.Get<OptionalAttributeClassWithFactory>();
                classWithFactory.GetParameter().ShouldEqual("parameter");


                injector.Bind<string>().ToConstant(constName);
                classWithFactory = injector.Get<OptionalAttributeClassWithFactory>();
                classWithFactory.GetParameter().ShouldEqual(constName);
            }
        }*/

        #region Nested type: OptionalAttributeClass

        public class OptionalAttributeClass
        {
            public OptionalAttributeClass([OptionalParameter("parameter")] string parameter)
            {
                ConstructorParameter = parameter;
            }

            public string ConstructorParameter { get; set; }

            public string MethodParameter { get; set; }

            [OptionalParameter("Property")]
            public string Property { get; set; }

            [OptionalParameter]
            public IDisposable Default { get; set; }

            [OptionalParameter]
            public int DefaultValue { get; set; }

            [Inject]
            public void Method([OptionalParameter("methodParameter")] string methodParameter)
            {
                MethodParameter = methodParameter;
            }
        }

        public class OptionalAttributeClassWithFactory
        {
            public Func<string> GetParameter { get; set; }

            public OptionalAttributeClassWithFactory([OptionalParameter("parameter")] Func<string> getParameter)
            {
                GetParameter = getParameter;
            }
        }
        #endregion
    }
}